import direct.directbase.DirectStart
from direct.actor import Actor
from pandac.PandaModules import *
from direct.interval.MetaInterval import *

from direct.showbase import DirectObject

import maultasche as mt

class Picker(DirectObject.DirectObject):
   def __init__(_):
      #setup collision stuff

      _.picker= CollisionTraverser()
      _.queue=CollisionHandlerQueue()

      _.pickerNode=CollisionNode('mouseRay')
      _.pickerNP=camera.attachNewNode(_.pickerNode)

      _.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())

      _.pickerRay=CollisionRay()
      _.pickerNode.addSolid(_.pickerRay)
    
      _.worldPlane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, 0)))
      _.worldNode = CollisionNode('worldPlane')
      #_.worldNode.addSolid(_.worldPlane)
      #_.worldNode.setIntoCollideMask(GeomNode.getDefaultCollideMask())
      #_.worldNodePath=NodePath()
      #_.worldNP = _.worldNodePath.attachNewNode(_.worldNode)
    
      #_.handler = CollisionHandlerEvent()
      #_.handler.addInPattern('mouseRay-into-worldPlane') 
      #_.accept('mouseRay-into-worldPlane', _.planeMove)

      #_.picker.addCollider(_.worldNP, _.handler)
      #_.picker.addCollider(_.worldNP, _.queue)
      _.picker.addCollider(_.pickerNP, _.queue)
      
      #this holds the object that has been picked
      _.pickedObj=None

      _.flag = loader.loadModel('zup-axis')
      _.flag.reparentTo(render)

      _.accept('mouse1', _.printMe)
      _.accept('mouse3', _.moveMe)
     

   #this function is meant to flag an object as being somthing we can pick
   def makePickable(_,newObj):
      newObj.setTag('pickable','true')

   #this function finds the closest object to the camera that has been hit by our ray
   def getObjectHit(_, mpos): #mpos is the position of the mouse on the screen
      _.pickedObj=None #be sure to reset this
      _.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY())
      _.picker.traverse(render)
      if _.queue.getNumEntries() > 0:
         _.queue.sortEntries()
         
         collision = _.queue.getEntry(0)
         _.pickedObj= collision.getIntoNodePath()

         parent=_.pickedObj.getParent()
         _.pickedObj=None

         while parent != render:
            if parent.getTag('pickable')=='true':
##               if parent.company:
##                    _.pickedObj=parent
##                    return company
##               else:
                    _.pickedObj=parent
                    return parent
            else:
               parent=parent.getParent()
      return None


   def getPickedObj(_):
         return _.pickedObj

   def printMe(_):
      if base.mouseWatcherNode.hasMouse():
           print "parent ", _.getObjectHit( base.mouseWatcherNode.getMouse())
           print _.pickedObj
   def planeMove(_, entry):
       #if _.pickedObj:
           print "move! move! moveeeee!"

   def moveMe(_):
      if _.pickedObj:
        maus = base.mouseWatcherNode.getMouse()
        
        # figure out parametric line equation
        _.pickerRay.setFromLens(base.camNode, maus.getX(),maus.getY())
        
        pointvec = _.pickerRay.getDirection()
        raypoint = _.pickerRay.getOrigin()
        
        camx = base.camera.getX()
        camy = base.camera.getY()
        camz = base.camera.getZ()
        
        #pt2 = [raypoint.getX(), raypoint.getY(), raypoint.getZ()]
        pt1 = [camx, camy, camz]
        pt2 = [pointvec.getX(), pointvec.getY(), pointvec.getZ()]

        print 'pt1 : ', pt1
        print 'pt2 : ', pt2

        # find 't' in our parametric line
        # we know that z is = 0
        # 0 = z1 + t*(z2 - z1)
        # -z1 = t*(z2 - z1)
        # -z1 / (z2 - z1) = t
        
        t = -(pt1[2]) / (pt2[2] - pt1[2]) 

        # now find our x and y
        dest = Point3(pt1[0] + (t * (pt2[0] - pt1[0])),# / 400,
                      pt1[1] + (t * (pt2[1] - pt1[1])),# / 300,
                      1)
        
        print 'dest : ', dest
        
        #np = Point3()
        #fp = Point3()
        #base.camLens.extrude(maus, np, fp)
        #np[0] += 
        #np[1] += 
        #dest = Point3(np[0],np[1],1) 
        _.flag.setPos(dest)
#        dest = Point3(maus.getX()*10, maus.getY()*10, 1)
            
        #if isinstance(_.pickedObj, mt.Unit):
        dist = dest - _.pickedObj.getPos()
        eta = dist.length() / 3.0
        
##        dest = NodePath
        
        #_.pickedObj.setPos(maus.getX(),maus.getY(),0) #FIXME
        myInterval= _.pickedObj.posInterval(eta,
            dest)#, startPos=_.pickedObj.getPos())
        #_.pickedObj.lookAt(dest)
        #rotInterval= _.pickedObj.hprInterval(3.0,
        #    dist * 10)
        #rotSequence = Sequence(rotInterval)
        #rotSequence.start()
        _.pickedObj.lookAt(dest)
        
        mySequence = Sequence(myInterval)
        #mySequence = Sequence(rotInterval, myInterval)
        mySequence.start()
        
        print "zoom! " + str(eta) + " units travelled!"
        #else:
        #    print "tried to move immobile object :/"
        
##        _.pickedObj=None #be sure to reset this
##        _.pickerRay.setFromLens(base.camNode, maus.getX(),maus.getY())
##        _.picker.traverse(render)
##        if _.queue.getNumEntries() > 0:
##            _.queue.sortEntries()
##            _.entry = _.queue.getEntry(0)
##            _.pickedObj=_.entry.getIntoNodePath()
##
##            parent=_.pickedObj.getParent()
##            _.pickedObj=None
##
##            while parent != render:
##                if isinstance(parent, CollisionPlane):
##                    _.pickedObj=parent
##                    return parent
##                else:
##                    parent=parent.getParent()

##
##      _.pickerRay.setFromLens(base.camNode, maus.getX(),maus.getY())
##      _.picker.traverse(render)
##      if _.queue.getNumEntries() > 0:
##         _.queue.sortEntries()
##         
##         collision = _.queue.getEntry(0)
##         _.pickedObj= collision.getIntoNodePath()
##
##         parent=_.pickedObj.getParent()
##         _.pickedObj=None
##
##         while parent != render:
##            if (parent.name == 'terrain'):
####               if parent.company:
####                    _.pickedObj=parent
####                    return company
####               else:
##                    _.pickedObj=parent
##                    return parent
##            else:
##               parent=parent.getParent()
